package org.mobilesynergies.android.epic.service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.mobilesynergies.android.epic.service.interfaces.IEpicServiceApplicationInterface;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;

/**
 * 
 * @author Peter Rautek
 *
 * This class provides a wrapper for a Android Application using the EPIC Service.
 * Extending this class is a easy starting point for a distributed application since it handles Android specifics for service binding and lifecycle management.   
 */
public abstract class RemoteActivity extends Activity {
	private static String CLASS_TAG = RemoteActivity.class.getSimpleName(); 

	/** The interface we will be calling on the service. */
	protected EpicServiceApplicationInterface mEpicService = null;
	/** True if the android.os.service (not to be confused with the EpicService) is bound successfully */
	protected boolean mIsBound = false;

	/** 
	 * This function is called when the Epic service was detected on the device and is waiting for interaction with your application.
	 * This is the point to check for version requirements and to setup your distributed application. 
	 */
	public abstract void initialize();
	
	/**
	 * This function is called when the Epic service shut down unexpectedly.
	 * This is not due to an network error or anything making the Epic service unavailable; It is probably a crash of the service.
	 * You cannot talk to the service anymore (since it crashed).
	 * Shut down your application or try to recover a connection later.
	 */
	public abstract void onServiceFailure();

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		String strServiceName = IEpicServiceApplicationInterface.class.getName();
		startService(new Intent(strServiceName));
		if(!bindService()){
			Log.e(CLASS_TAG, "couldn't start the service");
			//TODO check if it is installed
			//TODO if not point user to download
			//and quit activity?
		}
	}
	
	private boolean bindService() {

		if(mIsBound){
			return true;
		}
		String strServiceName = IEpicServiceApplicationInterface.class.getName();
		if(bindService(new Intent(strServiceName), mServiceConnection, Context.BIND_AUTO_CREATE)){
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Class for interacting with the main interface of the service.
	 */
	private ServiceConnection mServiceConnection = new ServiceConnection() {
		public void onServiceConnected(ComponentName className, IBinder service) {
			// This is called when the connection with the service has been
			// established, giving us the service object we can use to
			// interact with the service.  We are communicating with our
			// service through an IDL interface, so get a client-side
			// representation of that from the raw service object.

			mEpicService = (EpicServiceApplicationInterface) EpicServiceApplicationInterface.asInterface(service);
			mIsBound = true;
			initialize();
		}

		public void onServiceDisconnected(ComponentName className) {
			// This is called when the connection with the service has been
			// unexpectedly disconnected -- that is, its process crashed.
			mEpicService = null;
			mIsBound=false;
			onServiceFailure();
		}
	};

	
	protected String importEpicManifest(int iRessource) throws IOException{
		InputStream is = getResources().openRawResource(iRessource);
		return inputStreamToString(is);

	}

	private String inputStreamToString(InputStream in) throws IOException   {
		BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in));
		StringBuilder stringBuilder = new StringBuilder();
		String line = null;

		while ((line = bufferedReader.readLine()) != null) {
			stringBuilder.append(line + "\n");
		}

		bufferedReader.close();
		return stringBuilder.toString();
	}


	@Override
	protected void onResume() {
		super.onResume();
		if(!bindService()){
			Log.e(CLASS_TAG, "couldn't start the service");
			//TODO point user to download!
		}
	}

	@Override
	protected void onDestroy() {
		if(mServiceConnection!=null){
			unbindService(mServiceConnection);
		}
		mEpicService = null;
		mIsBound = false;
		super.onDestroy();
	}

}



